import hashlib
import json
from datetime import datetime
from hte.settings import BASE_DIR, MEDIA_ROOT
import requests
import os
from hte import settings


class MLPMJobsClient:
    def __init__(self, username, password, server):
        self.username = username
        self.password = password
        self.server = server
        self.session = requests.session()

    def encrypt_password(self, timestamp):
        """
        计算 `Authorization` 的值
        :param timestamp: 时间戳
        :return: 返回加密结果
        """
        md5 = hashlib.md5(f'{self.password}@{timestamp}'.encode('utf-8'))
        return md5.hexdigest()

    def do_request(self, method, url, params=None, data=None):
        """
        发送请求
        :param method:
        :param url:
        :param params:
        :param data:
        :return:
        """
        utc_now = datetime.utcnow().timestamp()
        resp = self.session.request(method, f'{self.server}{url}?_={utc_now}',
                                    params=params, data=data,
                                    auth=(self.username, self.encrypt_password(utc_now)))
        return resp

    def submit(self, username, description, func_name, *args, **kwargs):
        """
        提交任务
        :param username:
        :param func_name:
        :param description:
        :param args:
        :param kwargs:
        :return:
        """
        method = 'POST'
        url = '/api/v1/tasks/submit'
        data = {'username': username,
                'desc': description,
                'name': func_name,
                'args': json.dumps(args),
                'kwargs': json.dumps(kwargs)}

        return self.do_request(method, url, data=data)

    def submitWithFile(self, username, description, filename, func_name=None, *args, **kwargs):
        '''

        :param username:
        :param description:
        :param func_name:
        :param args:
        :param kwargs:
        :return:
        '''
        method = 'POST'
        url = '/api/v1/upload'
        file = {'file': open(os.path.join(MEDIA_ROOT, filename), 'rb')}
        data = {
            'username': username,
            'desc': description,
            'name': func_name,
            'args': json.dumps(args),
            'kwargs': json.dumps(kwargs),
        }
        utc_now = datetime.utcnow().timestamp()
        resp = self.session.request(method, f'{self.server}{url}?_={utc_now}',
                                    data=data, files=file,
                                    auth=(self.username, self.encrypt_password(utc_now)))
        return resp

    def terminate(self, task_id):
        """
        强制停止任务
        :param task_id:
        :return:
        """
        method = 'POST'
        url = f'/api/v1/task/{task_id}/terminate'

        return self.do_request(method, url)

    def info(self, task_id):
        """
        获取任务信息
        :param task_id:
        :return:
        """
        method = 'GET'
        url = f'/api/v1/task/{task_id}/info'

        return self.do_request(method, url)

    def result(self, task_id):
        """
        获取任务结果
        :param task_id:
        :return:
        """
        method = 'GET'
        url = f'/api/v1/task/{task_id}/result'

        return self.do_request(method, url)

    def list(self, username, page=1, per_page=10):
        """
        获取某一用户的任务列表
        :param username:
        :param page:
        :param per_page:
        :return:
        """
        method = 'GET'
        url = f'/api/v1/tasks/list'
        params = {'username': username,
                  'page': page,
                  'per_page': per_page}

        return self.do_request(method, url, params=params)

    def list_functions(self, page=1, per_page=10):
        """
        获取当前存在的所有任务函数
        :param page:
        :param per_page:
        :return:
        """
        method = 'GET'
        url = f'/api/v1/task_funcs/list'
        params = {'page': page,
                  'per_page': per_page}

        return self.do_request(method, url, params=params)

    def get_file(self, filename):
        method = 'GET'
        url = f'/api/v1/download/{filename}'
        return self.do_request(method, url)


if __name__ == '__main__':
    client_job = MLPMJobsClient(settings.MLPM_USERNAME, settings.MLPM_PASSWORD, settings.MLPM_JOB_SERVER)
    resp = client_job.get_file('6xBSGvq58exMh7wqgIz8.xlsx')
    with open('6xBSGvq58exMh7wqgIz8.xlsx', 'wb') as f:
        for chunk in resp.iter_content(100000):
            f.write(chunk)
    print(resp.status_code)
